﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Prism.Events;
using CPlatePrintSys.Annotation.Models;
using CPlatePrintSys.Annotation.Events;
using CPlatePrintSys.Domain.Models;
using CPlatePrintSys.Domain.Events;

namespace CPlatePrintSys.Annotation.Controls
{
    /// <summary>
    /// 基于Canvas的Parts布局控件，提供2D交互体验
    /// </summary>
    public class PartsLayoutControl : Canvas
    {
        private IEventAggregator _eventAggregator;
        private SheetLayoutInfo _sheetInfo;
        private Dictionary<string, FrameworkElement> _partVisuals = new Dictionary<string, FrameworkElement>();
        private FrameworkElement _selectedPartVisual;
        private string _selectedPartId;
        
        // 颜色定义 - 根据图片设计调整
        private readonly SolidColorBrush _sheetBrush = new SolidColorBrush(Color.FromRgb(240, 240, 240)); // 浅灰色Sheet
        private readonly SolidColorBrush _partBrush = new SolidColorBrush(Color.FromRgb(64, 64, 64)); // 深灰色Part
        private readonly SolidColorBrush _highlightBrush = new SolidColorBrush(Colors.DodgerBlue); // 蓝色高亮边框
        private readonly SolidColorBrush _borderBrush = new SolidColorBrush(Color.FromRgb(180, 180, 180)); // 亮灰色边框，更清晰可见
        private readonly SolidColorBrush _textBrush = new SolidColorBrush(Colors.White); // 白色文字
        private readonly SolidColorBrush _dimensionBrush = new SolidColorBrush(Colors.White); // 白色标注线
        private readonly SolidColorBrush _backgroundBrush = new SolidColorBrush(Color.FromRgb(33, 40, 48)); // 深灰色背景
        
        // 拖拽相关字段
        private bool _isDragging = false;
        private Point _dragStartMousePos;
        private Point _dragStartPartPos;
        private FrameworkElement _dragVisual = null;
        
        // 碰撞检测阈值（5mm）
        private const double CollisionThreshold = 5.0;
        
        // 缩放比例（将实际尺寸转换为显示尺寸）
        private double _scale = 1.0;
        private const double MaxDisplayWidth = 800.0;
        private const double MaxDisplayHeight = 600.0;
        
        // 当前控件的可用显示区域
        private Size _availableDisplaySize = new Size(MaxDisplayWidth, MaxDisplayHeight);
        
        public PartsLayoutControl()
        {
            this._eventAggregator = (IEventAggregator)Prism.Ioc.ContainerLocator.Container.Resolve(typeof(IEventAggregator));
            
            // 设置Canvas背景 - 根据图片设计使用深灰色背景
            this.Background = _backgroundBrush;
            
            // 绑定事件
            this.MouseLeftButtonDown += OnMouseLeftButtonDown;
            this.MouseMove += OnMouseMove;
            this.MouseLeftButtonUp += OnMouseLeftButtonUp;
            this.MouseEnter += OnMouseEnter;
            this.MouseLeave += OnMouseLeave;
            
            // 订阅事件
            this._eventAggregator.GetEvent<DisplaySheetLayoutEvent>().Subscribe(OnDisplaySheetLayout);

            SubscribeRotateEvents();
            
            // 订阅大小变化事件
            this.SizeChanged += OnSizeChanged;
            
            // 订阅加载完成事件，解决第一次进入时布局过小的问题
            this.Loaded += OnLoaded;
        }

        /// <summary>
        /// 处理控件加载完成事件，获取实际大小并重新计算缩放比例
        /// </summary>
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            // 获取控件的实际大小
            if (this.ActualWidth > 0 && this.ActualHeight > 0)
            {
                _availableDisplaySize = new Size(this.ActualWidth, this.ActualHeight);
                
                // 如果有Sheet信息，重新计算缩放比例并刷新显示
                if (_sheetInfo != null)
                {
                    System.Diagnostics.Debug.WriteLine($"[OnLoaded] Actual size: {this.ActualWidth}x{this.ActualHeight}, Refreshing display");
                    RefreshDisplay();
                }
            }
        }
        
        private void OnDisplaySheetLayout(SheetLayoutInfo sheetLayoutInfo)
        {
            if (sheetLayoutInfo != null)
                DisplaySheetAndParts(sheetLayoutInfo);
        }
        
        /// <summary>
        /// 处理控件大小变化事件
        /// </summary>
        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            System.Diagnostics.Debug.WriteLine($"[OnSizeChanged] Size changed from {e.PreviousSize} to {e.NewSize}");
            
            if (e.NewSize.Width > 0 && e.NewSize.Height > 0)
            {
                // 更新可用显示大小
                _availableDisplaySize = e.NewSize;
                System.Diagnostics.Debug.WriteLine($"[OnSizeChanged] Updated _availableDisplaySize to {_availableDisplaySize}");
                
                // 如果有Sheet信息，重新计算缩放比例并刷新显示
                if (_sheetInfo != null)
                {
                    System.Diagnostics.Debug.WriteLine($"[OnSizeChanged] Refreshing display with new size");
                    RefreshDisplay();
                }
            }
        }
        
        /// <summary>
        /// 刷新显示
        /// </summary>
        private void RefreshDisplay()
        {
            if (_sheetInfo != null)
            {
                DisplaySheetAndParts(_sheetInfo);
            }
        }
        
        public void DisplaySheetAndParts(SheetLayoutInfo sheet)
        {
            this.Children.Clear();
            _partVisuals.Clear();
            _sheetInfo = sheet;
            _selectedPartVisual = null;
            
            if (sheet == null) return;
            
            // 第一次调用时，如果_availableDisplaySize还是默认值，尝试获取控件的实际大小
            if (_availableDisplaySize.Width <= MaxDisplayWidth && _availableDisplaySize.Height <= MaxDisplayHeight)
            {
                if (this.ActualWidth > 0 && this.ActualHeight > 0)
                {
                    _availableDisplaySize = new Size(this.ActualWidth, this.ActualHeight);
                    System.Diagnostics.Debug.WriteLine($"[DisplaySheetAndParts] First call - Updated _availableDisplaySize to actual size: {_availableDisplaySize}");
                }
            }
            
            // 计算缩放比例
            CalculateScale(sheet.Length, sheet.Width);
            
            // 显示Sheet边界
            DisplaySheet(sheet);
            
            // 显示尺寸标注
            DisplayDimensions(sheet.Length, sheet.Width);
            
            // 显示所有Part
            if (sheet.Parts != null)
            {
                foreach (var part in sheet.Parts)
                {
                    DisplayPart(part);
                }
            }
            
            // 验证所有Part是否都被正确添加
            System.Diagnostics.Debug.WriteLine($"[DisplaySheetAndParts] Canvas Children count: {this.Children.Count}");
            System.Diagnostics.Debug.WriteLine($"[DisplaySheetAndParts] Parts count: {sheet.Parts?.Count ?? 0}");
            System.Diagnostics.Debug.WriteLine($"[DisplaySheetAndParts] Current scale: {_scale}");
        }
        
        private void CalculateScale(double sheetLength, double sheetWidth)
        {
            // 优先使用动态的可用显示大小，如果没有则尝试使用控件的实际大小
            double availableWidth = _availableDisplaySize.Width > 0 ? _availableDisplaySize.Width - 100 : 
                                  (this.ActualWidth > 0 ? this.ActualWidth - 100 : MaxDisplayWidth - 100);
            double availableHeight = _availableDisplaySize.Height > 0 ? _availableDisplaySize.Height - 100 : 
                                   (this.ActualHeight > 0 ? this.ActualHeight - 100 : MaxDisplayHeight - 100);
            
            System.Diagnostics.Debug.WriteLine($"[CalculateScale] Sheet size: {sheetLength}x{sheetWidth}");
            System.Diagnostics.Debug.WriteLine($"[CalculateScale] Available display size: {availableWidth}x{availableHeight}");
            System.Diagnostics.Debug.WriteLine($"[CalculateScale] _availableDisplaySize: {_availableDisplaySize}");
            System.Diagnostics.Debug.WriteLine($"[CalculateScale] Actual size: {this.ActualWidth}x{this.ActualHeight}");
            
            double scaleX = availableWidth / sheetLength;
            double scaleY = availableHeight / sheetWidth;
            _scale = Math.Min(scaleX, scaleY) * 0.8; // 留出边距
            
            // 确保缩放比例在合理范围内
            _scale = Math.Max(0.001, Math.Min(10.0, _scale));
            
            System.Diagnostics.Debug.WriteLine($"[CalculateScale] Calculated scale: {_scale} (scaleX: {scaleX}, scaleY: {scaleY})");
        }
        
        private void DisplaySheet(SheetLayoutInfo sheet)
        {
            // 创建Sheet矩形 - 根据图片设计调整
            var sheetRect = new Rectangle
            {
                Width = sheet.Length * _scale,
                Height = sheet.Width * _scale,
                Fill = new SolidColorBrush(Colors.Transparent), // 透明背景，符合设计
                Stroke = _borderBrush, // 黑色边框
                StrokeThickness = 1 // 更细的边框，符合设计
            };
            
            Canvas.SetLeft(sheetRect, 50); // 留出左边距用于标注
            Canvas.SetTop(sheetRect, 50);  // 留出上边距用于标注
            
            this.Children.Add(sheetRect);
        }
        
        private void DisplayDimensions(double length, double width)
        {
            // 水平尺寸线（下方）- 根据图片设计调整
            var dimLineH = new Line
            {
                X1 = 50,
                Y1 = width * _scale + 80,
                X2 = 50 + length * _scale,
                Y2 = width * _scale + 80,
                Stroke = _dimensionBrush, // 白色标注线
                StrokeThickness = 1 // 更细的线条，符合设计
            };
            this.Children.Add(dimLineH);
            
            // 水平尺寸线两端的垂直线条（延伸线）
            var leftExtensionH = new Line
            {
                X1 = 50,
                Y1 = width * _scale + 75,
                X2 = 50,
                Y2 = width * _scale + 85,
                Stroke = _dimensionBrush, // 白色延伸线
                StrokeThickness = 1
            };
            this.Children.Add(leftExtensionH);
            
            var rightExtensionH = new Line
            {
                X1 = 50 + length * _scale,
                Y1 = width * _scale + 75,
                X2 = 50 + length * _scale,
                Y2 = width * _scale + 85,
                Stroke = _dimensionBrush, // 白色延伸线
                StrokeThickness = 1
            };
            this.Children.Add(rightExtensionH);
            
            // 水平尺寸标注
            var textH = new TextBlock
            {
                Text = $"{length} cm",
                Foreground = _dimensionBrush, // 白色文字
                FontSize = 12,
                HorizontalAlignment = HorizontalAlignment.Center
            };
            Canvas.SetLeft(textH, 50 + length * _scale / 2 - 30);
            Canvas.SetTop(textH, width * _scale + 85);
            this.Children.Add(textH);
            
            // 垂直尺寸线（右侧）- 根据图片设计调整
            var dimLineV = new Line
            {
                X1 = length * _scale + 80,
                Y1 = 50,
                X2 = length * _scale + 80,
                Y2 = 50 + width * _scale,
                Stroke = _dimensionBrush, // 白色标注线
                StrokeThickness = 1 // 更细的线条，符合设计
            };
            this.Children.Add(dimLineV);
            
            // 垂直尺寸线两端的水平线条（延伸线）
            var topExtensionV = new Line
            {
                X1 = length * _scale + 75,
                Y1 = 50,
                X2 = length * _scale + 85,
                Y2 = 50,
                Stroke = _dimensionBrush, // 白色延伸线
                StrokeThickness = 1
            };
            this.Children.Add(topExtensionV);
            
            var bottomExtensionV = new Line
            {
                X1 = length * _scale + 75,
                Y1 = 50 + width * _scale,
                X2 = length * _scale + 85,
                Y2 = 50 + width * _scale,
                Stroke = _dimensionBrush, // 白色延伸线
                StrokeThickness = 1
            };
            this.Children.Add(bottomExtensionV);
            
            // 垂直尺寸标注
            var textV = new TextBlock
            {
                Text = $"{width} cm",
                Foreground = _dimensionBrush, // 白色文字
                FontSize = 12,
                HorizontalAlignment = HorizontalAlignment.Center
            };
            Canvas.SetLeft(textV, length * _scale + 85);
            Canvas.SetTop(textV, 50 + width * _scale / 2 - 10);
            this.Children.Add(textV);
        }
        
        private void DisplayPart(PartLayoutInfo part)
        {
            // 添加调试日志
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] PartId: {part.PartId}, Rotation: {part.PartRotation}, Position: ({part.Position.X}, {part.Position.Y})");
            
            // 计算旋转后的有效尺寸
            bool swap = (Math.Abs(part.PartRotation % 180) == 90);
            double effectiveWidth = swap ? part.Height : part.Width;
            double effectiveHeight = swap ? part.Width : part.Height;
            
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Swap: {swap}, EffectiveWidth: {effectiveWidth}, EffectiveHeight: {effectiveHeight}");
            
            // 计算显示尺寸 - 始终使用原始尺寸，不根据旋转调整
            double originalDisplayWidth = part.Width * _scale;
            double originalDisplayHeight = part.Height * _scale;
            
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Original Display Size: ({originalDisplayWidth}, {originalDisplayHeight})");
            
            // 创建Part容器 - 使用Border作为容器，始终使用原始尺寸
            var partContainer = new Border
            {
                Width = originalDisplayWidth,  // 始终使用原始宽度
                Height = originalDisplayHeight, // 始终使用原始高度
                Background = _partBrush, // 深灰色填充
                BorderBrush = (part.PartId == _selectedPartId) ? _highlightBrush : _borderBrush, // 选中时蓝色边框，否则亮灰色边框
                BorderThickness = new Thickness((part.PartId == _selectedPartId) ? 3 : 2), // 增加边框厚度，确保可见
                Tag = part.PartId
            };
            
            // 添加文件名文本 - 根据图片设计调整
            if (!string.IsNullOrEmpty(part.FileName))
            {
                var textBlock = new TextBlock
                {
                    Text = part.FileName,
                    Foreground = _textBrush, // 白色文字
                    FontSize = Math.Max(8, Math.Min(Math.Min(part.Width, part.Height) * _scale * 0.25, 14)),
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    TextWrapping = TextWrapping.Wrap,
                    FontWeight = FontWeights.Normal, // 正常字重
                    TextAlignment = TextAlignment.Center
                };
                
                partContainer.Child = textBlock;
            }
            
            // 设置位置 - 直接使用Canvas.SetLeft/SetTop
            Canvas.SetLeft(partContainer, 50 + part.Position.X * _scale);
            Canvas.SetTop(partContainer, 50 + part.Position.Y * _scale);
            
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Container Size: ({partContainer.Width}, {partContainer.Height}), Position: ({Canvas.GetLeft(partContainer)}, {Canvas.GetTop(partContainer)})");
            
            // 先添加到Canvas，确保布局完成
            this.Children.Add(partContainer);
            
            // 检查Part是否成功添加
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Part added to Canvas. Children count: {this.Children.Count}");
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Part is in Children: {this.Children.Contains(partContainer)}");
            
            // 强制布局更新
            partContainer.UpdateLayout();
            
            // 应用旋转变换 - 只使用RotateTransform，基于Border的实际尺寸
            var rotateTransform = new RotateTransform(part.PartRotation);
            rotateTransform.CenterX = partContainer.ActualWidth / 2.0; // 使用实际宽度的一半作为旋转中心X
            rotateTransform.CenterY = partContainer.ActualHeight / 2.0; // 使用实际高度的一半作为旋转中心Y
            
            // 使用RenderTransform
            partContainer.RenderTransform = rotateTransform;
            
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Transform: Angle={rotateTransform.Angle}, CenterX={rotateTransform.CenterX}, CenterY={rotateTransform.CenterY}");
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] RenderTransform applied: {partContainer.RenderTransform != null}");
            
            // 添加更多调试信息
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Container ActualWidth: {partContainer.ActualWidth}, ActualHeight: {partContainer.ActualHeight}");
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Container RenderSize: {partContainer.RenderSize}");
            System.Diagnostics.Debug.WriteLine($"[DisplayPart] Container DesiredSize: {partContainer.DesiredSize}");
            
            _partVisuals[part.PartId] = partContainer;
            
            if (part.PartId == _selectedPartId)
                _selectedPartVisual = partContainer;
        }
        
        private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var mousePos = e.GetPosition(this);
            var hitElement = GetElementAtPosition(mousePos);
            
            if (hitElement != null && hitElement.Tag is string partId)
            {
                SelectPart(partId);
                
                // 准备拖拽
                if (_sheetInfo != null)
                {
                    _isDragging = true;
                    _dragStartMousePos = mousePos;
                    var part = _sheetInfo.Parts.FirstOrDefault(p => p.PartId == partId);
                    if (part != null)
                        _dragStartPartPos = part.Position;
                    
                    // 创建拖拽时的临时视觉对象
                    _dragVisual = CreateDragVisual(part);
                    this.Children.Add(_dragVisual);
                    
                    CaptureMouse();
                }
                
                e.Handled = true;
                return;
            }
            
            // 点击空白取消选中
            ClearSelection();
        }
        
        private FrameworkElement GetElementAtPosition(Point position)
        {
            // 从后往前检查（最上层的元素优先）
            for (int i = this.Children.Count - 1; i >= 0; i--)
            {
                var child = this.Children[i] as FrameworkElement;
                if (child != null && child.Tag is string)
                {
                    // 获取Part的实际位置和尺寸
                    double left = Canvas.GetLeft(child);
                    double top = Canvas.GetTop(child);
                    double width = child.Width;
                    double height = child.Height;
                    
                    // 检查鼠标位置是否在Part的矩形范围内
                    var originalRect = new Rect(left, top, width, height);
                    if (originalRect.Contains(position))
                    {
                        return child;
                    }
                    
                    // 如果Part有旋转变换，需要特殊处理
                    if (child.RenderTransform is RotateTransform rotateTransform)
                    {
                        // 计算旋转后的边界框
                        var rotatedRect = GetRotatedBoundingBox(left, top, width, height, rotateTransform.Angle);
                        if (rotatedRect.Contains(position))
                        {
                            return child;
                        }
                    }
                    else if (child.RenderTransform is TransformGroup transformGroup)
                    {
                        // 检查TransformGroup中的TranslateTransform
                        if (transformGroup.Children.Count > 0 && transformGroup.Children[0] is TranslateTransform translateTransform)
                        {
                            // 计算旋转后的边界框 - 使用简化的方法调用
                            // 注意：这里我们简化处理，直接使用原始边界
                            var transformGroupRect = new Rect(left, top, width, height);
                            if (transformGroupRect.Contains(position))
                            {
                                return child;
                            }
                        }
                    }
                }
            }
            return null;
        }
        
        private Rect GetRotatedBoundingBox(double left, double top, double width, double height, double angle)
        {
            // 将角度转换为弧度
            double radians = angle * Math.PI / 180.0;
            
            // 计算四个角点的坐标
            var points = new Point[]
            {
                new Point(left, top), // 左上角
                new Point(left + width, top), // 右上角
                new Point(left + width, top + height), // 右下角
                new Point(left, top + height) // 左下角
            };
            
            // 计算旋转中心
            double centerX = left + width / 2.0;
            double centerY = top + height / 2.0;
            
            // 旋转所有角点
            var rotatedPoints = new Point[4];
            for (int i = 0; i < 4; i++)
            {
                double dx = points[i].X - centerX;
                double dy = points[i].Y - centerY;
                
                rotatedPoints[i] = new Point(
                    centerX + dx * Math.Cos(radians) - dy * Math.Sin(radians),
                    centerY + dx * Math.Sin(radians) + dy * Math.Cos(radians)
                );
            }
            
            // 计算旋转后的边界框
            double minX = rotatedPoints.Min(p => p.X);
            double maxX = rotatedPoints.Max(p => p.X);
            double minY = rotatedPoints.Min(p => p.Y);
            double maxY = rotatedPoints.Max(p => p.Y);
            
            return new Rect(minX, minY, maxX - minX, maxY - minY);
        }
        
        /// <summary>
        /// 在逻辑坐标系中计算旋转后的边界框
        /// </summary>
        /// <param name="x">Part左上角的逻辑X坐标</param>
        /// <param name="y">Part左上角的逻辑Y坐标</param>
        /// <param name="width">Part的逻辑宽度</param>
        /// <param name="height">Part的逻辑高度</param>
        /// <param name="angle">旋转角度（度）</param>
        /// <returns>旋转后的边界框（逻辑坐标系）</returns>
        private Rect GetRotatedBoundingBoxLogical(double x, double y, double width, double height, double angle)
        {
            // 将角度转换为弧度
            double radians = angle * Math.PI / 180.0;
            
            // 计算四个角点的坐标（逻辑坐标系）
            var points = new Point[]
            {
                new Point(x, y), // 左上角
                new Point(x + width, y), // 右上角
                new Point(x + width, y + height), // 右下角
                new Point(x, y + height) // 左下角
            };
            
            // 计算旋转中心（逻辑坐标系）
            double centerX = x + width / 2.0;
            double centerY = y + height / 2.0;
            
            // 旋转所有角点
            var rotatedPoints = new Point[4];
            for (int i = 0; i < 4; i++)
            {
                double dx = points[i].X - centerX;
                double dy = points[i].Y - centerY;
                
                rotatedPoints[i] = new Point(
                    centerX + dx * Math.Cos(radians) - dy * Math.Sin(radians),
                    centerY + dx * Math.Sin(radians) + dy * Math.Cos(radians)
                );
            }
            
            // 计算旋转后的边界框（逻辑坐标系）
            double minX = rotatedPoints.Min(p => p.X);
            double maxX = rotatedPoints.Max(p => p.X);
            double minY = rotatedPoints.Min(p => p.Y);
            double maxY = rotatedPoints.Max(p => p.Y);
            
            return new Rect(minX, minY, maxX - minX, maxY - minY);
        }
        
        /// <summary>
        /// 计算旋转后边界框相对于未旋转Part左上角的偏移量
        /// </summary>
        /// <param name="width">Part的宽度</param>
        /// <param name="height">Part的高度</param>
        /// <param name="angle">旋转角度（度）</param>
        /// <returns>偏移量（X, Y）</returns>
        private Point GetRotatedBoundingBoxOffsets(double width, double height, double angle)
        {
            // 将角度转换为弧度
            double radians = angle * Math.PI / 180.0;
            
            // 计算四个角点的坐标（相对于Part左上角）
            var points = new Point[]
            {
                new Point(0, 0), // 左上角
                new Point(width, 0), // 右上角
                new Point(width, height), // 右下角
                new Point(0, height) // 左下角
            };
            
            // 计算旋转中心（相对于Part左上角）
            double centerX = width / 2.0;
            double centerY = height / 2.0;
            
            // 旋转所有角点
            var rotatedPoints = new Point[4];
            for (int i = 0; i < 4; i++)
            {
                double dx = points[i].X - centerX;
                double dy = points[i].Y - centerY;
                
                rotatedPoints[i] = new Point(
                    centerX + dx * Math.Cos(radians) - dy * Math.Sin(radians),
                    centerY + dx * Math.Sin(radians) + dy * Math.Cos(radians)
                );
            }
            
            // 计算旋转后的边界框（相对于Part左上角）
            double minX = rotatedPoints.Min(p => p.X);
            double maxX = rotatedPoints.Max(p => p.X);
            double minY = rotatedPoints.Min(p => p.Y);
            double maxY = rotatedPoints.Max(p => p.Y);
            
            // 返回边界框左上角相对于Part左上角的偏移量
            return new Point(minX, minY);
        }

        private FrameworkElement CreateDragVisual(PartLayoutInfo part)
        {
            // 使用与DisplayPart相同的逻辑 - 始终使用原始尺寸
            double originalDisplayWidth = part.Width * _scale;
            double originalDisplayHeight = part.Height * _scale;
            
            var dragVisual = new Border
            {
                Width = originalDisplayWidth,  // 使用原始宽度，与Part显示一致
                Height = originalDisplayHeight, // 使用原始高度，与Part显示一致
                Background = new SolidColorBrush(Colors.Transparent), // 透明背景
                BorderBrush = _highlightBrush, // 蓝色边框
                BorderThickness = new Thickness(2), // 更细的边框，符合设计
                Opacity = 0.8 // 半透明
            };
            
            // 设置位置
            Canvas.SetLeft(dragVisual, 50 + part.Position.X * _scale);
            Canvas.SetTop(dragVisual, 50 + part.Position.Y * _scale);
            
            // 应用旋转变换 - 使用与Part相同的逻辑
            if (Math.Abs(part.PartRotation) > 0.001)
            {
                var transform = new RotateTransform(part.PartRotation);
                transform.CenterX = originalDisplayWidth / 2.0; // 使用原始尺寸的一半作为旋转中心X
                transform.CenterY = originalDisplayHeight / 2.0; // 使用原始尺寸的一半作为旋转中心Y
                dragVisual.RenderTransform = transform;
            }
            
            return dragVisual;
        }
        
        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            // 更新光标
            UpdateCursor(e.GetPosition(this));
            
            // 处理拖拽
            if (_isDragging && _selectedPartId != null && _sheetInfo != null && e.LeftButton == MouseButtonState.Pressed)
            {
                var mousePos = e.GetPosition(this);
                var part = _sheetInfo.Parts.FirstOrDefault(p => p.PartId == _selectedPartId);
                if (part == null) return;
                
                // 计算新位置（逻辑坐标系）
                double dx = (mousePos.X - _dragStartMousePos.X) / _scale;
                double dy = (mousePos.Y - _dragStartMousePos.Y) / _scale;
                double newX = _dragStartPartPos.X + dx;
                double newY = _dragStartPartPos.Y + dy;
                
                System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Raw position: ({newX}, {newY})");
                
                // 计算旋转后的有效尺寸
                bool swap = (Math.Abs(part.PartRotation % 180) == 90);
                double effectiveWidth = swap ? part.Height : part.Width;
                double effectiveHeight = swap ? part.Width : part.Height;
                
                System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Effective size: ({effectiveWidth}, {effectiveHeight}), Sheet size: ({_sheetInfo.Length}, {_sheetInfo.Width})");
                
                // 使用旋转边界框进行边界检测
                double constrainedX = newX;
                double constrainedY = newY;
                
                if (Math.Abs(part.PartRotation) > 0.001)
                {
                    // 对于旋转的Part，使用旋转边界框进行边界检测
                    var rotatedBoundingBox = GetRotatedBoundingBoxLogical(newX, newY, part.Width, part.Height, part.PartRotation);
                    
                    System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Rotated bounding box: Left={rotatedBoundingBox.Left}, Top={rotatedBoundingBox.Top}, Width={rotatedBoundingBox.Width}, Height={rotatedBoundingBox.Height}");
                    
                    // 约束旋转后的边界框到Sheet范围内
                    double constrainedLeft = Math.Max(0, Math.Min(rotatedBoundingBox.Left, _sheetInfo.Length - rotatedBoundingBox.Width));
                    double constrainedTop = Math.Max(0, Math.Min(rotatedBoundingBox.Top, _sheetInfo.Width - rotatedBoundingBox.Height));
                    
                    // 计算边界框偏移量
                    var bbOffsets = GetRotatedBoundingBoxOffsets(part.Width, part.Height, part.PartRotation);
                    
                    // 从约束后的边界框左上角反向计算Part的左上角位置
                    constrainedX = constrainedLeft - bbOffsets.X;
                    constrainedY = constrainedTop - bbOffsets.Y;
                }
                else
                {
                    // 对于未旋转的Part，使用简单的边界约束
                    constrainedX = Math.Max(0, Math.Min(newX, _sheetInfo.Length - effectiveWidth));
                    constrainedY = Math.Max(0, Math.Min(newY, _sheetInfo.Width - effectiveHeight));
                }
                
                System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Constrained position: ({constrainedX}, {constrainedY})");
                
                // 碰撞检测
                Point adjustedPosition;
                if (!CheckCollision(part.PartId, constrainedX, constrainedY, part.Width, part.Height, out adjustedPosition))
                {
                    // 更新拖拽视觉对象位置 - 使用与DisplayPart相同的计算方式
                    double displayX = 50 + constrainedX * _scale;
                    double displayY = 50 + constrainedY * _scale;
                    Canvas.SetLeft(_dragVisual, displayX);
                    Canvas.SetTop(_dragVisual, displayY);
                    System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Drag visual position: ({displayX}, {displayY})");
                }
                else
                {
                    // 如果发生碰撞，则更新拖拽视觉对象位置到调整后的位置
                    double displayX = 50 + adjustedPosition.X * _scale;
                    double displayY = 50 + adjustedPosition.Y * _scale;
                    Canvas.SetLeft(_dragVisual, displayX);
                    Canvas.SetTop(_dragVisual, displayY);
                    System.Diagnostics.Debug.WriteLine($"[OnMouseMove] Adjusted drag visual position: ({displayX}, {displayY})");
                }
            }
        }
        
        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (_isDragging && _selectedPartId != null && _sheetInfo != null)
            {
                _isDragging = false;
                ReleaseMouseCapture();
                
                var mousePos = e.GetPosition(this);
                var part = _sheetInfo.Parts.FirstOrDefault(p => p.PartId == _selectedPartId);
                if (part != null)
                {
                    // 计算最终位置（逻辑坐标系）
                    double dx = (mousePos.X - _dragStartMousePos.X) / _scale;
                    double dy = (mousePos.Y - _dragStartMousePos.Y) / _scale;
                    double newX = _dragStartPartPos.X + dx;
                    double newY = _dragStartPartPos.Y + dy;
                    
                    System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Raw position: ({newX}, {newY})");
                    
                    // 计算旋转后的有效尺寸
                    bool swap = (Math.Abs(part.PartRotation % 180) == 90);
                    double effectiveWidth = swap ? part.Height : part.Width;
                    double effectiveHeight = swap ? part.Width : part.Height;
                    
                    System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Effective size: ({effectiveWidth}, {effectiveHeight}), Sheet size: ({_sheetInfo.Length}, {_sheetInfo.Width})");
                    
                    // 使用旋转边界框进行边界检测
                    double constrainedX = newX;
                    double constrainedY = newY;
                    
                    if (Math.Abs(part.PartRotation) > 0.001)
                    {
                        // 对于旋转的Part，使用旋转边界框进行边界检测
                        var rotatedBoundingBox = GetRotatedBoundingBoxLogical(newX, newY, part.Width, part.Height, part.PartRotation);
                        
                        System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Rotated bounding box: Left={rotatedBoundingBox.Left}, Top={rotatedBoundingBox.Top}, Width={rotatedBoundingBox.Width}, Height={rotatedBoundingBox.Height}");
                        
                        // 约束旋转后的边界框到Sheet范围内
                        double constrainedLeft = Math.Max(0, Math.Min(rotatedBoundingBox.Left, _sheetInfo.Length - rotatedBoundingBox.Width));
                        double constrainedTop = Math.Max(0, Math.Min(rotatedBoundingBox.Top, _sheetInfo.Width - rotatedBoundingBox.Height));
                        
                        // 计算边界框偏移量
                        var bbOffsets = GetRotatedBoundingBoxOffsets(part.Width, part.Height, part.PartRotation);
                        
                        // 从约束后的边界框左上角反向计算Part的左上角位置
                        constrainedX = constrainedLeft - bbOffsets.X;
                        constrainedY = constrainedTop - bbOffsets.Y;
                    }
                    else
                    {
                        // 对于未旋转的Part，使用简单的边界约束
                        constrainedX = Math.Max(0, Math.Min(newX, _sheetInfo.Length - effectiveWidth));
                        constrainedY = Math.Max(0, Math.Min(newY, _sheetInfo.Width - effectiveHeight));
                    }
                    
                    System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Constrained position: ({constrainedX}, {constrainedY})");
                    
                    // 碰撞检测
                    Point adjustedPosition;
                    if (!CheckCollision(part.PartId, constrainedX, constrainedY, part.Width, part.Height, out adjustedPosition))
                    {
                        part.Position = new Point(constrainedX, constrainedY);
                        System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Final position: ({constrainedX}, {constrainedY})");
                    }
                    else
                    {
                        part.Position = adjustedPosition;
                        System.Diagnostics.Debug.WriteLine($"[OnMouseLeftButtonUp] Adjusted final position: ({adjustedPosition.X}, {adjustedPosition.Y})");
                    }
                }
                
                // 移除拖拽视觉对象
                if (_dragVisual != null)
                {
                    this.Children.Remove(_dragVisual);
                    _dragVisual = null;
                }
                
                // 重新显示所有part
                DisplaySheetAndParts(_sheetInfo);
            }
        }
        
        private bool CheckCollision(string currentPartId, double x, double y, double width, double height, out Point adjustedPosition)
        {
            adjustedPosition = new Point(x, y);
            
            // 获取当前Part的信息
            var currentPart = _sheetInfo.Parts.FirstOrDefault(p => p.PartId == currentPartId);
            if (currentPart == null) return false;
            
            // 检查是否与其他Part碰撞，如果碰撞则调整位置到阈值边界
            foreach (var other in _sheetInfo.Parts)
            {
                if (other.PartId == currentPartId) continue;
                
                // 使用旋转后的边界框进行碰撞检测
                var currentBoundingBox = GetRotatedBoundingBoxLogical(x, y, currentPart.Width, currentPart.Height, currentPart.PartRotation);
                var otherBoundingBox = GetRotatedBoundingBoxLogical(other.Position.X, other.Position.Y, other.Width, other.Height, other.PartRotation);
                
                System.Diagnostics.Debug.WriteLine($"[CheckCollision] Current bounding box: Left={currentBoundingBox.Left}, Top={currentBoundingBox.Top}, Width={currentBoundingBox.Width}, Height={currentBoundingBox.Height}");
                System.Diagnostics.Debug.WriteLine($"[CheckCollision] Other bounding box: Left={otherBoundingBox.Left}, Top={otherBoundingBox.Top}, Width={otherBoundingBox.Width}, Height={otherBoundingBox.Height}");
                
                // 扩展边界框以包含阈值
                var currentExpandedRect = new Rect(
                    currentBoundingBox.Left - CollisionThreshold, 
                    currentBoundingBox.Top - CollisionThreshold,
                    currentBoundingBox.Width + CollisionThreshold * 2, 
                    currentBoundingBox.Height + CollisionThreshold * 2);
                var otherExpandedRect = new Rect(
                    otherBoundingBox.Left - CollisionThreshold, 
                    otherBoundingBox.Top - CollisionThreshold,
                    otherBoundingBox.Width + CollisionThreshold * 2, 
                    otherBoundingBox.Height + CollisionThreshold * 2);
                
                if (currentExpandedRect.IntersectsWith(otherExpandedRect))
                {
                    System.Diagnostics.Debug.WriteLine($"[CheckCollision] Collision detected between {currentPartId} and {other.PartId}");
                    
                    // 计算调整后的位置，使其刚好在阈值边界
                    double adjustedX = x;
                    double adjustedY = y;
                    
                    // 检查水平方向的重叠
                    if (currentExpandedRect.Left < otherExpandedRect.Right && currentExpandedRect.Right > otherExpandedRect.Left)
                    {
                        // 当前Part在右侧
                        if (currentBoundingBox.Left > otherBoundingBox.Left)
                        {
                            // 计算调整后的位置，使当前Part的边界框刚好在阈值边界
                            double targetLeft = otherBoundingBox.Right + CollisionThreshold;
                            var currentOffsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                            adjustedX = targetLeft - currentOffsets.X;
                        }
                        // 当前Part在左侧
                        else
                        {
                            // 计算调整后的位置，使当前Part的边界框刚好在阈值边界
                            double targetLeft = otherBoundingBox.Left - currentBoundingBox.Width - CollisionThreshold;
                            var currentOffsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                            adjustedX = targetLeft - currentOffsets.X;
                        }
                    }
                    
                    // 检查垂直方向的重叠
                    if (currentExpandedRect.Top < otherExpandedRect.Bottom && currentExpandedRect.Bottom > otherExpandedRect.Top)
                    {
                        // 当前Part在下方
                        if (currentBoundingBox.Top > otherBoundingBox.Top)
                        {
                            // 计算调整后的位置，使当前Part的边界框刚好在阈值边界
                            double targetTop = otherBoundingBox.Bottom + CollisionThreshold;
                            var currentOffsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                            adjustedY = targetTop - currentOffsets.Y;
                        }
                        // 当前Part在上方
                        else
                        {
                            // 计算调整后的位置，使当前Part的边界框刚好在阈值边界
                            double targetTop = otherBoundingBox.Top - currentBoundingBox.Height - CollisionThreshold;
                            var currentOffsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                            adjustedY = targetTop - currentOffsets.Y;
                        }
                    }
                    
                    // 确保调整后的位置在Sheet边界内
                    var adjustedBoundingBox = GetRotatedBoundingBoxLogical(adjustedX, adjustedY, currentPart.Width, currentPart.Height, currentPart.PartRotation);
                    if (adjustedBoundingBox.Left < 0)
                    {
                        var offsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                        adjustedX = -offsets.X;
                    }
                    if (adjustedBoundingBox.Top < 0)
                    {
                        var offsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                        adjustedY = -offsets.Y;
                    }
                    if (adjustedBoundingBox.Right > _sheetInfo.Length)
                    {
                        var offsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                        adjustedX = _sheetInfo.Length - adjustedBoundingBox.Width - offsets.X;
                    }
                    if (adjustedBoundingBox.Bottom > _sheetInfo.Width)
                    {
                        var offsets = GetRotatedBoundingBoxOffsets(currentPart.Width, currentPart.Height, currentPart.PartRotation);
                        adjustedY = _sheetInfo.Width - adjustedBoundingBox.Height - offsets.Y;
                    }
                    
                    adjustedPosition = new Point(adjustedX, adjustedY);
                    System.Diagnostics.Debug.WriteLine($"[CheckCollision] Adjusted position: ({adjustedX}, {adjustedY})");
                    return true; // 表示发生了碰撞，需要调整位置
                }
            }
            
            return false; // 没有碰撞
        }
        
        private void UpdateCursor(Point mousePos)
        {
            if (!string.IsNullOrEmpty(_selectedPartId) && _sheetInfo != null)
            {
                var hitElement = GetElementAtPosition(mousePos);
                if (hitElement != null && hitElement.Tag is string partId && partId == _selectedPartId)
                {
                    this.Cursor = Cursors.SizeAll;
                }
                else
                {
                    this.Cursor = Cursors.Arrow;
                }
            }
        }
        
        private void OnMouseEnter(object sender, MouseEventArgs e)
        {
            UpdateCursor(e.GetPosition(this));
        }
        
        private void OnMouseLeave(object sender, MouseEventArgs e)
        {
            this.Cursor = Cursors.Arrow;
        }
        
        private void SelectPart(string partId)
        {
            _selectedPartId = partId;
            _selectedPartVisual = null;
            DisplaySheetAndParts(_sheetInfo);
            _eventAggregator.GetEvent<PartSelectedEvent>().Publish(partId);
        }
        
        private void ClearSelection()
        {
            _selectedPartVisual = null;
            _selectedPartId = null;
            DisplaySheetAndParts(_sheetInfo);
        }
        
        private void SubscribeRotateEvents()
        {
            _eventAggregator.GetEvent<RotateSelectedPartEvent>().Subscribe(RotateSelectedPart);
        }
        
        private void RotateSelectedPart(double angle)
        {
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] Start - Angle: {angle}, SelectedPartId: {_selectedPartId}");
            
            if (_sheetInfo == null || string.IsNullOrEmpty(_selectedPartId))
            {
                MessageBox.Show("请先选中一个零件！");
                return;
            }
            
            var part = _sheetInfo.Parts?.FirstOrDefault(p => p.PartId == _selectedPartId);
            if (part == null)
            {
                MessageBox.Show("请先选中一个零件！");
                return;
            }
            
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] Before rotation - PartId: {part.PartId}, CurrentRotation: {part.PartRotation}, Position: ({part.Position.X}, {part.Position.Y})");
            
            // 计算新的旋转角度 - 修复角度计算逻辑
            double newRotation = part.PartRotation + angle;
            // 保持角度在-360到360范围内，但不强制转换为正数
            while (newRotation > 360) newRotation -= 360;
            while (newRotation < -360) newRotation += 360;
            
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] New rotation calculated: {newRotation}");
            
            // 判断是否需要交换宽高 - 修复判断逻辑
            bool swap = (Math.Abs(newRotation % 180) == 90);
            double effectiveWidth = swap ? part.Height : part.Width;
            double effectiveHeight = swap ? part.Width : part.Height;
            
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] Swap: {swap}, EffectiveWidth: {effectiveWidth}, EffectiveHeight: {effectiveHeight}");
            
            // 检查旋转后是否会超出边界 - 使用旋转后的边界框
            var rotatedBoundingBox = GetRotatedBoundingBoxLogical(part.Position.X, part.Position.Y, part.Width, part.Height, newRotation);
            if (rotatedBoundingBox.Left < 0 || rotatedBoundingBox.Top < 0 || 
                rotatedBoundingBox.Right > _sheetInfo.Length || rotatedBoundingBox.Bottom > _sheetInfo.Width)
            {
                MessageBox.Show("旋转后零件会超出Sheet边界，操作取消！");
                return;
            }
            
            // 重叠检查
            Point adjustedPosition;
            if (CheckCollision(part.PartId, part.Position.X, part.Position.Y, part.Width, part.Height, out adjustedPosition))
            {
                // 如果发生碰撞，显示提示信息
                MessageBox.Show("旋转后零件会与其他零件重叠，操作取消！");
                return;
            }
            
            // 只更新旋转角度，不改变位置
            part.PartRotation = newRotation;
            
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] After rotation - PartId: {part.PartId}, NewRotation: {part.PartRotation}, Position: ({part.Position.X}, {part.Position.Y})");
            
            // 刷新显示
            DisplaySheetAndParts(_sheetInfo);
            
            System.Diagnostics.Debug.WriteLine($"[RotateSelectedPart] Display refreshed");
        }
        
        /// <summary>
        /// 保存当前布局信息到LayoutInfo的Merged部分
        /// </summary>
        /// <returns>LayoutInfo对象</returns>
        public LayoutInfo SaveLayoutInfo()
        {
            if (_sheetInfo == null)
                return null;
                
            var layoutInfo = new LayoutInfo
            {
                LayoutMean = "2", // 合并布局
                Merged = new MergedLayout
                {
                    SheetLongth = _sheetInfo.Length,
                    SheetWidth = _sheetInfo.Width,
                    PartLayouts = new List<PartLayout>()
                }
            };
            
            if (_sheetInfo.Parts != null)
            {
                foreach (var part in _sheetInfo.Parts)
                {
                    var partLayout = new PartLayout
                    {
                        SheetConsistentNo = part.PartId,
                        Position = new Position
                        {
                            X = part.Position.X,
                            Y = part.Position.Y
                        },
                        Rotation = part.PartRotation
                    };
                    
                    layoutInfo.Merged.PartLayouts.Add(partLayout);
                }
            }
            
            return layoutInfo;
        }
        
        /// <summary>
        /// 从LayoutInfo的Merged部分加载布局信息
        /// </summary>
        /// <param name="layoutInfo">布局信息</param>
        public void LoadLayoutInfo(LayoutInfo layoutInfo)
        {
            if (layoutInfo?.Merged == null)
                return;
                
            var sheetInfo = new SheetLayoutInfo
            {
                SheetId = "LoadedSheet",
                Length = layoutInfo.Merged.SheetLongth,
                Width = layoutInfo.Merged.SheetWidth,
                Parts = new List<PartLayoutInfo>()
            };
            
            if (layoutInfo.Merged.PartLayouts != null)
            {
                foreach (var partLayout in layoutInfo.Merged.PartLayouts)
                {
                    var part = new PartLayoutInfo
                    {
                        PartId = partLayout.SheetConsistentNo,
                        Position = new Point(partLayout.Position.X, partLayout.Position.Y),
                        PartRotation = partLayout.Rotation,
                        Width = 100, // 默认值，实际应该从DXF文件获取
                        Height = 100  // 默认值，实际应该从DXF文件获取
                    };
                    
                    sheetInfo.Parts.Add(part);
                }
            }
            
            DisplaySheetAndParts(sheetInfo);
        }
    }
}
